let term = new Terminal({
    theme: {
        background: '#1f1f1f'
    }
});
let vm = new VirtualMachine();
let supportsTouch = 'ontouchstart' in document;
let availableKeys = [];
let debugMode = false;

function loadProgram(name, program) {
    term.clear();
    term.focus();
    vm.reset();
    availableKeys = [];
    vm.loadRom(lc3os);
    let res = vm.loadRom(program);
    if (res == EXIT_SUCCESS) {
        // term.write(`Select Program is : ${name}\r\n`);
        vm.run();
    } else {
        term.write(`Select Program Format Error!\r\n`);
    }
}

function switchDebug() {
    debugMode = !debugMode;
    if (debugMode) {
        document.getElementById('switchDebug').innerHTML = '关闭调试';
    } else {
        document.getElementById('switchDebug').innerHTML = '打开调试';
    }
    vm.setDebugMode(debugMode);
}

function selectRom() {
    let ele = document.getElementById("fileInput");
    let fileList = ele.files;
    let file = fileList[0];

    let fileReader = new FileReader();
    fileReader.readAsArrayBuffer(file);
    fileReader.onload = function() {
        loadProgram(file.name, new Uint8Array(fileReader.result));
    }
}

function next() {
    if (vm.debugMode) {
        vm.run();
    }
}

// 初始化终端
function initTerm() {

    Terminal.applyAddon(fit);

    let termContainer = document.getElementById('terminal');
    term.open(termContainer);
    term.write('Choose a game to begin.\r\n');
    term.fit();

    term.on('key', function(char, e) { // eslint-disable-line no-unused-vars
        if (char === '\r') char = '\n';
        availableKeys.push(char.charCodeAt(0));
        vm.interrupt();
    });
}

// 初始化虚拟机
function initVM() {
    // MARK: - display
    let pendingWrites = '';

    vm.putChar = function(val) {
        var char = String.fromCharCode(val);
        if (char === '\n') char = '\r\n';

        if (pendingWrites.length == 0) {
            window.requestAnimationFrame(() => {
                term.write(pendingWrites);
                pendingWrites = [];
            });
        }

        pendingWrites += char;
    };

    vm.hasChar = function() {
        return availableKeys.length > 0;
    };

    let n = 0;
    vm.getChar = function() {
        if (availableKeys.length > 0) {
            return availableKeys.splice(0, 1)[0];
        } else {
            return 0;
        }
    };

    vm.stepAfter = function(instr) {
        if (debugMode) {
            let op = instr >> 12;
            console.log(`指令：0x${instr.toString(16)} 操作码：${op.toString(16)} opbit:${(1 << op).toString(16)}
                reg[0]:${vm.reg[0].toString(16)} reg[1]:${vm.reg[1].toString(16)} reg[2]:${vm.reg[2].toString(16)} reg[3]:${vm.reg[3].toString(16)} reg[4]:${vm.reg[4].toString(16)} reg[5]:${vm.reg[5].toString(16)} reg[6]:${vm.reg[6].toString(16)} reg[7]:${vm.reg[7].toString(16)} reg[8]:${vm.reg[8].toString(16)} reg[9]:${vm.reg[9].toString(16)}`);
        }
    }
}

window.onload = function() {
    initTerm();
    initVM();
}

